package com.lz.ovuola.util.date;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;

/**
 * Instant——它代表的是时间戳 Local Date——不包含具体时间的日期，比如2014-01-14。它可以用来存储生日，周年纪念日，入职日期等。
 * LocalTime——它代表的是不含日期的时间 LocalDateTime——它包含了日期及时间，不过还是没有偏移信息或者说时区。
 * ZonedDateTime——这是一个包含时区的完整的日期时间，偏移量是以UTC/格林威治时间为基准的。
 * 
 * @author fz
 *
 */
public abstract class DateUtils {
	/**
	 * 获取当前时间后 几天、几周、几月后的日期
	 * 
	 * @param units
	 * @param chronoUnit
	 *            时间单位
	 * @return
	 */
	public static final Date getAfterSeveralUnits(int units,
			ChronoUnit chronoUnit) {
		return localDateTimeToDate(LocalDateTime.now().plus(units, chronoUnit));
	}

	/**
	 * 
	 * @param date
	 * @param units
	 * @param chronoUnit
	 * @return
	 */
	public static final Date getAfterSeveralUnits(Date date, int units,
			ChronoUnit chronoUnit) {
		return localDateTimeToDate(dateToLocalDateTime(date).plus(units,
				chronoUnit));
	}

	/**
	 * 获取几天后的日期
	 * 
	 * @param units
	 * @param chronoUnit
	 *            时间单位
	 * @return
	 */
	public static final Long getAfterSeveralUnitsReturn(int units) {
		return Instant.now().plus(units, ChronoUnit.DAYS).toEpochMilli();
	}

	/**
	 * 相等判断
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static final boolean eq(Date date1, Date date2) {
		return dateToLocalDateTime(date1).equals(dateToLocalDateTime(date2));
	}

	/**
	 * 大于判断
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static final boolean gt(Date date1, Date date2) {
		return dateToLocalDateTime(date1).isAfter(dateToLocalDateTime(date2));
	}

	/**
	 * LocalDateTime 转Date
	 * 
	 * @param localDateTime
	 * @return
	 */
	private static final Date localDateTimeToDate(LocalDateTime localDateTime) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}

	/**
	 * Date转LocalDateTime
	 * 
	 * @param date
	 * @return
	 */
	public static final LocalDateTime dateToLocalDateTime(Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		return LocalDateTime.ofInstant(instant, zone);
	}

	// private static final Date localDateToDate(LocalDate localDate) {
	// return localDate.toDate();
	// }
	/**
	 * Date转LocalDate
	 * 
	 * @param date
	 * @return
	 */
	public static final java.time.LocalDate dateToLocalDate(Date date) {
		return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
	}

	/**
	 * 两日期天数之差，date2必须大于date1
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static final int calDateToDay(Date date1, Date date2) {
		LocalDate start = new LocalDate(date1);
		LocalDate end = new LocalDate(date2);
		return Days.daysBetween(start, end).getDays();
	}

	/**
	 * 两日期小时之差，date2必须大于date1
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static final int calDateToHours(Date date1, Date date2) {
		DateTime dateTime1 = new DateTime(date1);
		DateTime dateTime2 = new DateTime(date2);
		return dateTime2.getHourOfDay() - dateTime1.getHourOfDay()
				+ calDateToDay(dateTime1.toDate(), dateTime2.toDate()) * 24;
	}

	// public static void main(String[] args) throws ParseException {//
	// .toEpochMilli()
	//
	// SimpleDateFormat dateFormat = new SimpleDateFormat(
	// "yyyy-MM-dd HH:mm:ss");
	//
	// System.out.println(calDateToDay(
	// dateFormat.parse("2018-12-01 00:12:12"),
	//
	// dateFormat.parse("2018-12-01 23:11:11")));
	// System.out.println(calDateToHours(
	// dateFormat.parse("2018-12-02 9:12:12"),
	//
	// dateFormat.parse("2018-12-03 10:11:11")));
	//
	// System.out.println(dateToLocalDate(dateFormat
	// .parse("2018-12-03 10:11:11")));
	// System.out.println(DateUtils.dateToLocalDateTime(dateFormat
	// .parse("2018-12-03 23:11:11")).getHour()
	// );
	// }
}
